functor Shrink (S : SHRINK_STRUCTS) : SHRINK =
struct
  open S

  structure Cfg = Cfg
  
  structure ConstFold = ConstFold (structure Cfg = Cfg)
  structure ConstProp = ConstProp (structure Cfg = Cfg)
  structure CopyProp = CopyProp (structure Cfg = Cfg)
  structure ConstCond = ConstCond (structure Cfg = Cfg)
  structure DeadCode = DeadCode (structure Cfg = Cfg)
  structure Adce = Adce (structure Cfg = Cfg)
  structure BlockUnion = BlockUnion (structure Cfg = Cfg)
  structure DeadBlock = DeadBlock (structure Cfg = Cfg)
  structure DeadDec = DeadDec (structure Cfg = Cfg)
  
  
  val tag = false
  fun output (f, name) =
      if tag
      then Cfg.Program.toDot (f, name)
      else ()
      
  fun outputReverse (f, name) =
      if tag
      then Cfg.Program.reverseToDot (f, name)
      else ()
  
  fun localShrink new =
      let val _ = output (new, "BeforeOpt")
          val _ = outputReverse (new, "Reverse")
          
          val new = ConstProp.shrink new
          val _ = output (new, "ConstProp1_1")
          
          val new = ConstFold.shrink new
          val _ = output (new, "ConstFold1_2")
          
          val new = ConstProp.shrink new
          val _ = output (new, "ConstProp2_3")
          
          val new = ConstFold.shrink new
          val _ = output (new, "ConstFold2_4")
          
          val new = CopyProp.shrink new          
          val _ = output (new, "CopyProp1_5")
          
          val new = ConstCond.shrink new
          val _ = output (new, "ConstCond1_6")
          
          val new = DeadBlock.shrink new
          val _ = output (new, "DeadBlock1_7")
          
          val new = ConstProp.shrink new
          val _ = output (new, "ConstProp3_8")
          
          val new = BlockUnion.shrink new
          val _ = output (new, "BlockUnion1_9")
          
          val new = DeadBlock.shrink new
          val _ = output (new, "DeadBlock2_10")
          
          val new = ConstProp.shrink new
          val _ = output (new, "ConstProp4_11")
                
          val new = DeadCode.shrink new
          val _ = output (new, "DeadCode1_12")
          
          val new = BlockUnion.shrink new
          val _ = output (new, "BlockUnion2_13")
          
          val new = DeadBlock.shrink new
          val _ = output (new, "DeadBlock3_14")
          
          val new = CopyProp.shrink new    
          val _ = output (new, "CopyProp2_15")          
          
          val new = Adce.shrink new
          val _ = output (new, "Adce1_16")
          
          val new = DeadDec.shrink new
          val _ = output (new, "deaddec1_17")
          
          val _ = output (new, "finalAfterSsa")
          
      in  new
      end
      
  fun globlShrink new = new
  
  fun shrink new = 
      if !Control.doSsaOpt
      then localShrink new
      else new
end
